
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;

using Swaf;
using Swaf.BizObj;
using Swaf.Container;
using Swaf.Gui;
using Swaf.Gui.AspNet2;
using FilterSort.Gui.AspNet;

namespace Articles.Gui.AspNet
{
	[Themeable(true)]
	[ParseChildren(true)]
	public class StandAloneArticleListDisplay : Swaf.Gui.AspNet2.UserControl
	{
		protected List<FilterOption> m_filters = new List<FilterOption>();
		protected List<SortOption> m_orderBy = new List<SortOption>();
		protected FlexiMap m_macros = new FlexiMap();

		public StandAloneArticleListDisplay(): base(){}
		public StandAloneArticleListDisplay(ActiveWidget widget) : base(widget) { }

		[PersistenceModeAttribute(PersistenceMode.InnerProperty)]
		public List<FilterOption> Filter { get { return m_filters; } }

		[PersistenceModeAttribute(PersistenceMode.InnerProperty)]
		public List<SortOption> Sort { get { return m_orderBy; } }

		public void setupOptionsFromBizObj(IBizObj salObj)
		{
			foreach (IBizObjField fld in salObj.type.OrderedFields)
			{
				if (fld.Name.CompareTo("ESF") == 0)
					break;
				if (string.Compare(fld.Name, "id", true) != 0)
				{
					string fieldVal = (string)salObj.get(fld.Name);
					if (fieldVal != null)
						Cmn.callPropertySet(this, fld.Name, fieldVal, true);
				}
			}
			if (BPC != null)
			{
				IWidget childList = BPC.HostView.findWidget("gl" + ID);
				if (childList != null)
				{
					BPC.removeActiveBizProc("g" + ID);
					BPC.removeBizProcOfflineState("g" + ID);
					BPC.ActiveWidgets.Remove("gl" + ID);
					BPC.PageState.WidgetStates.Remove(childList.WidgetId);

					clearControls();
					createControls();
				}
			}
			//string filterSortCriteria = (string)salObj.get("filtersortCriteria");
		}

		[Category("Appearance")]
		public string PID { get { return (string)m_macros.get("pid"); } set { m_macros.put("pid", value); } }

		[Category("Appearance")]
		public string ParentBizProc { get { return (string)m_macros.get("parentBizProc"); } set { m_macros.put("parentBizProc", value); } }

		[Category("Appearance")]
		public string BoxSkinId { get { return (string)m_macros.get("skinId"); } set { m_macros.put("skinId", value); } }

		[Category("Appearance")]
		public string ChildBoxSkinId { get { return (string)m_macros.get("childSkinId"); } set { m_macros.put("childSkinId", value); } }

		[Category("Appearance")]
		public string ListTemplate { get { return (string)m_macros.get("listType"); } set { m_macros.put("listType", value); } }

		[Category("Appearance")]
		public string NavLink { get { return (string)m_macros.get("navLink2"); } set { m_macros.put("navLink2", value); } }

		[Category("Appearance")]
		public string ImageRes { get { return (string)m_macros.get("imageRes"); } set { m_macros.put("imageRes", value); } }

		[Category("Appearance")]
		public string MaxElements { get { return (string)m_macros.get("maxElements"); } set { m_macros.put("maxElements", value); } }

		[Category("Appearance")]
		public string ColumnElements { get { return (string)m_macros.get("colElements"); } set { m_macros.put("colElements", value); } }

		[Category("Appearance")]
		public string DetailLevel { get { return (string)m_macros.get("detailLevel"); } set { m_macros.put("detailLevel", value); } }

        [Category("Appearance")]
        public string IncludeSelf { get { return (string)m_macros.get("includeSelf"); } set { m_macros.put("includeSelf", value); } }

		[Category("Appearance")]
		public string EntireTree { get { return (string)m_macros.get("entireTree"); } set { m_macros.put("entireTree", value); } }

		[Category("Appearance")]
		public string AnimiType { get { return (string)m_macros.get("animiType"); } set { m_macros.put("animiType", value); } }

		[Category("Appearance")]
		public string ListCssClass { get { return (string)m_macros.get("listCssClass"); } set { m_macros.put("listCssClass", value); } }

		[Category("Appearance")]
		public string ChildCssClass { get { return (string)m_macros.get("childCssClass"); } set { m_macros.put("childCssClass", value); } }

		[Category("Appearance")]
		public string ReadMoreText { get { return (string)m_macros.get("readMoreText"); } set { m_macros.put("readMoreText", value); } }

		[Category("Appearance")]
		public string TreeName { get { return (string)m_macros.get("treeName"); } set { m_macros.put("treeName", value); } }

		[Category("Appearance")]
		public bool ResetDepth { get { return (m_macros.get("resetDepth") is bool) ? (bool)m_macros.get("resetDepth") : false; } set { m_macros.put("resetDepth", value); } }

		[Category("Appearance")]
		public bool UsePagedDataSource { get { return (m_macros.get("pageData") is bool) ? (bool)m_macros.get("pageData") : true; } set { m_macros.put("pageData", value); } }

		[Category("Appearance")]
		public bool IncludeCounts { get { return (m_macros.get("incCounts") is bool) ? (bool)m_macros.get("incCounts") : false; } set { m_macros.put("incCounts", value); } }

		[Category("Appearance")]
		public string UseAssociationName { get { return (string)getMacroVal("associationName", ""); } set { m_macros.put("associationName", value); } }

        public bool DontIncrementViewCount { get { return (m_macros.get("DontIncrementViewCount") is bool) ? (bool)m_macros.get("DontIncrementViewCount") : false; } set { m_macros.put("DontIncrementViewCount", value); } }

		protected object getMacroVal(string name, object defVal)
		{
			object v = m_macros.get(name);
			return v == null ? defVal : v;
		}

        protected override string createCacheKey()
		{
			string key = base.createCacheKey() + WidgetId;
			s_content[key] = null;
			return key;
		}

		protected virtual void setupMacros()
		{
			if (NavLink == null)
				NavLink = "$CmpSetting(sitePath)$/articles/$CalcArticleIds($pid$,$uniqueId$)$.aspx";
			if (ParentBizProc == null)
				ParentBizProc = "<ParentBizProc id=\"loginBP\" />";
			else
				ParentBizProc = string.Format("<ParentBizProc id=\"{0}\" fieldName=\"id\" dataId=\"pid\" />", ParentBizProc);

			if (PID != null)
				m_macros.put("fullPid", string.Format("pid=\"{0}\"", PID));
			else
			{
				PID = "";
				m_macros.put("fullPid", "");
			}

			if (MaxElements == null)
				MaxElements = "-1";
			if (DetailLevel == null)
				DetailLevel = "basicDetails";
			if (ImageRes == null)
				ImageRes = "Thumbnail";
			if (IncludeSelf == null)
				IncludeSelf = "True";
			if (EntireTree == null)
				EntireTree = "True";
			if (ChildCssClass == null)
				ChildCssClass = "articlebox";
			if (TreeName == null)
				TreeName = "Articles";
			if (ColumnElements == null)
				ColumnElements = "1";
			if (Cmn.IsEmpty(UseAssociationName))
				UseAssociationName = "";

			m_macros["resetDepth"] = !ResetDepth ? "" : "resetDepth='true'";
			m_macros["pageSize"] = UsePagedDataSource ? "" : "pageSize='10000'";
			m_macros["includeCounts"] = !IncludeCounts ? "" : "includeCounts='true'";

			m_macros.put("cssClass", CssClass);
			m_macros.put("id", ID);
		}

		protected override System.IO.TextReader Html
		{
			get
			{
				setupMacros();
				string html = base.Html.ReadToEnd();
				html = Swaf.Application.currentApp.resMgr.resolve(html, m_macros);
				html = html.Replace("$navLink$", ((string)m_macros.get("navLink2")));//.Replace("&","&amp;"));
				return new System.IO.StringReader(html);
			}
		}

		protected BizProc ArticleBizProc
		{
			get
			{
				foreach (Control ctl in Controls)
					if (ctl is BizProc)
						return (BizProc)ctl;
				return null;
			}
		}

		protected void setupFilterSort()
		{
			ArticleBizProc.TheBizProc.FilterSortCriteria = FilterSortOption.createFilterSortOption(Filter, Sort);
		}

		protected override bool createControls()
		{
			bool rc =  base.createControls();
			ArticleBizProc.BizProcCreated = bizProcCreated;
			return rc;
		}

		protected void bizProcCreated(object bizProc)
		{
			setupFilterSort();
		}
	
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
			string scriptUrl = Page.ClientScript.GetWebResourceUrl(typeof(ArticleTranslationDisplay), "ScsAspNet.Articles.Gui.AspNet.script.ArtForms.js");
            Page.ClientScript.RegisterClientScriptInclude("Articles.ArtFormScript", scriptUrl);
			setupFilterSort();
		}
    }

	public class FilterSortOption
	{
		public static IBizObj createFilterSortOption(List<FilterOption> filters, List<SortOption> sorts)
		{
			IBizObj filterSort = null;
			if (sorts.Count > 0 || filters.Count > 0)
			{
				filterSort = Application.currentApp.bizObjMgr.create("FilterSortOptions");
				if (sorts.Count > 0)
					foreach (SortOption sortOp in sorts)
					{
						IBizObj s = ((IBizObjList)filterSort.get("sortOptions")).insertNew();
						s.put("field", sortOp.Field);
						s.put("isAsc", sortOp.IsAsc);
					}
				if (filters.Count > 0)
					foreach (FilterOption filterOp in filters)
					{
						IBizObj f = ((IBizObjList)filterSort.get("filterOptions")).insertNew();
						f.put("field", filterOp.Field);
						f.put("criteria", filterOp.Criteria);
						f.put("value", filterOp.Value);
					}
			}
			return filterSort;
		}
	}
	/// <summary>
	/// Used by UI controls that want to expose a strong type for filter sort options.
	/// </summary>
	/// <remarks>A UI control that wants to allow filter/sort criteria to be embedded within
	/// it can use this.  Specifically, the StandAloneArticleListDisplay, which contains an 
	/// embedded BizProc is using this to allow the list of articles it shows to be filtered/sorted
	/// based on values specified in the aspx using it.
	/// 
	/// The BizProc user control could also use this.</remarks>
	/// 
	[Serializable]
	public class FilterOption
	{
		protected string m_field = null;
		protected string m_criteria = null;
		protected string m_value = null;

		public FilterOption()
		{
		}

		public FilterOption(string field, string criteria, string value)
		{
			Field = field;
			Criteria = criteria;
			Value = value;
		}

		public string Field { get { return m_field; } set { m_field = value; } }
		public string Criteria { get { return m_criteria; } set { m_criteria = value; } }
		public string Value { get { return m_value; } set { m_value = value; } }
	}

	[Serializable]
	public class SortOption
	{
		protected string m_field = null;
		protected bool m_isAsc = true;

		public SortOption()
		{
		}
		public SortOption(string field, bool isAsc)
		{
			Field = field;
			IsAsc = isAsc;
		}

		public string Field { get { return m_field; } set { m_field = value; } }
		public bool IsAsc { get { return m_isAsc; } set { m_isAsc = value; } }
	}
}
